#pragma once
#include <iostream>
#include <jsoncpp/json/json.h>
const char space = ' ';
const char line_break = '\n';
//#define myself 1
bool Header(std::string *package) //"len\n"
{
    // len
    std::string header;
    header += std::to_string(package->length());
    // len
    header += line_break;
    header += *package;
    *package = header;
    return true;
}
bool Deheader(std::string &package, std::string &content) //"len\n""10\n10 + 5\n"
{
    std::cout << "in the front:" << package << std::endl;
    int pos = package.find(line_break);
    if (pos == std::string::npos)
        return false;
    size_t len = std::stoi(package.substr(0, pos));
    if (package.length() - pos - 1 != len)
        return false;
    content = package.substr(pos + 1, len);
    // package=package.erase(0,pos+1+len);
    package.erase(0, pos + 1 + len);
    std::cout << "erased package:%d" << package.size() << std::endl;
    std::cout << "content:" << content << std::endl;
    std::cout << package << std::endl;
    return true;
}

enum ResCode
{
    Lose = 1,
    ZeroDivision,
    InvalidOperator,
    ZeroMode

};

class Request
{
public:
    Request(const int &x = 0, const int &y = 0, const char &op = ' ') : x_(x), y_(y), op_(op)
    {
    }

    bool Serialize(std::string *out) //"x op y"
    {
#ifndef myself
        // x序列化
        // std::cout<<"..x_:"<<x_<<std::endl;
        std::string target;
        target += std::to_string(x_);
        target += space;
        // x序列化

        // op序列化
        target += op_;
        target += space;
        // op序列化

        // y序列化
        target += std::to_string(y_);
        target += line_break;
        std::cout << x_ << std::endl;
        // y序列化
        *out = target;
#else
        Json::Value value;
        value["x"] = x_;
        value["y"] = y_;
        value["op"] = op_;
        Json::FastWriter w;
        *out = w.write(value);

#endif
        return true;
    }

    bool Deserialize(const std::string &in) // x op y\n
    {
#ifndef myself
        // x
        int pos0 = in.find(space);
        if (pos0 == std::string::npos)
            return false;
        x_ = std::stoi(in.substr(0, pos0));
        // std::cout<<"x_:"<<x_<<std::endl;
        //  x

        // op
        op_ = in[pos0 + 1];

        // op

        // 这里要有个判断是否合法
        if (in[pos0 + 2] != space)
            return false;
        // 这里要有个判断是否合法

        // y
        y_ = std::stoi(in.substr(pos0 + 2, in.length() - pos0 - 2));
        // y
#else
        Json::Reader r;
        Json::Value root;
        r.parse(in, root);
        x_ = root["x"].asInt();
        y_ = root["y"].asInt();
        op_ = root["op"].asInt();
#endif
        return true;
    }

public:
    int x_;
    int y_;
    char op_;
};

class Response
{
public:
    Response(const int &results = 0, const int &code = 0) : results_(results), code_(code)
    {
    }

    bool Serialize(std::string *out) //"result code\n"
    {
#ifndef myself
        *out += std::to_string(results_);
        *out += space;
        *out += std::to_string(code_);
        *out += line_break;
#else
        Json::Value v;
        v["results"] = results_;
        v["code"] = code_;
        Json::FastWriter w;
        *out = w.write(v);
#endif
        return true;
    }

    bool Deserialize(const std::string &in) //"result code\n"//100 10\n
    {
#ifndef myself
        // results
        int pos0 = in.find(space);
        results_ = std::stoi(in.substr(0, pos0));
        // results

        // code
        code_ = std::stoi(in.substr(pos0 + 1, in.length() - pos0 - 2));
        // code
#else
        Json::Reader r;
        Json::Value root;
        r.parse(in, root);
        results_ = root["results"].asInt();
        code_ = root["code"].asInt();
#endif
        return true;
    }

    int results_;
    int code_;
};